library(tidyverse)
library(janitor)
library(here)
community_belonging <- clean_names(read_csv(here("raw_data/community_belonging.csv")))
Rows: 43611 Columns: 13── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (11): FeatureCode, Measurement, Units, Community belonging, Gender, Urban Rural Classification, SIMD quintiles, Type Of Tenure, Household Type, Ethnicity,...
dbl  (2): DateCode, Value
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
green_spaces <- clean_names(read_csv(here("raw_data/green_spaces.csv")))
Rows: 38451 Columns: 13── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (11): FeatureCode, Measurement, Units, Distance to Nearest Green or Blue Space, Age, Gender, Urban Rural Classification, SIMD quintiles, Type Of Tenure, H...
dbl  (2): DateCode, Value
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
neighbourhood_rating <- clean_names(read_csv(here("raw_data/neighbourhood_rating.csv")))
Rows: 38055 Columns: 13── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (11): FeatureCode, Measurement, Units, Neighbourhood rating, Gender, Urban Rural Classification, SIMD quintiles, Type Of Tenure, Household Type, Ethnicity...
dbl  (2): DateCode, Value
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
community_belonging
green_spaces
neighbourhood_rating

Explore Community Belonging

community_belonging %>% 
   summarise(across(.cols = everything(), .fns = ~sum(is.na(.x))))

There are no NA values

community_belonging %>% 
  distinct(units)

There is only 1 value in this column. It can be removed in the cleaning script

community_belonging %>% 
  distinct() %>% 
  nrow()
[1] 43611
community_belonging %>% 
  nrow()
[1] 43611

No duplicates

community_belonging %>% 
  filter(feature_code == "S12000036", year == "2016",
         walking_distance_to_nearest_greenspace == "More than 10 minutes")
Error in `filter()`:
ℹ In argument: `year == "2016"`.
Caused by error in `year == "2016"`:
! comparison (==) is possible only for atomic and list types
Backtrace:
 1. community_belonging %>% ...
 3. dplyr:::filter.data.frame(...)
 4. dplyr:::filter_rows(.data, dots, by)
 5. dplyr:::filter_eval(...)
 7. mask$eval_all_filter(dots, env_filter)
 8. dplyr (local) eval()

There appear to be some missing values such as how many people voted “Don’t know” to community belonging where the walking distance is greater than 10 minutes. Is it sensible to assume this is 0?

community_belonging %>% 
  filter(feature_code == "S12000036", year == "2016",
         walking_distance_to_nearest_greenspace == "More than 10 minutes",
         measurement == "Percent") %>% 
  summarise(sum(value))

Yes, the others add up to 100% so 0% voted “Don’t know”.

What is the granularity of the data?

community_belonging %>% 
  filter(date_code == 2019,
         gender == "Female")

The feature codes look like council areas. The name of the area if going to be more useful than codes. data source

council_areas <- clean_names(read_csv(here("raw_data/council_area_codes.csv")))
Rows: 44 Columns: 14── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (7): CA, CAName, HSCP, HSCPName, HB, HBName, Country
dbl (7): _id, CADateEnacted, CADateArchived, HSCPDateEnacted, HSCPDateArchived, HBDateEnacted, HBDateArchived
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
council_areas_clean <- council_areas %>% 
  select(ca, ca_name) %>% 
  add_row(ca = "S92000003" ,ca_name = "Scotland")

Some rows appear to be for the whole of Scotland so I have added a row for this code.

community_belonging <- community_belonging %>% 
  left_join(council_areas_clean, by = c("feature_code" = "ca"))
Warning: Detected an unexpected many-to-many relationship between `x` and `y`.

When plotting the order of community belonging will not make sense, therefore this should be factored.

community_belonging <- community_belonging %>% 
  mutate(community_belonging = factor(community_belonging, 
                                      levels = c("Not at all strongly", 
                                                 "Not very strongly",
                                                 "Don't know",
                                                 "Fairly strongly",
                                                 "Very strongly")))

Each row appears to be a demographic (eg. Female, more than 10 minutes to nearest greenspace, etc), category of community belonging, measurement, and the percentage of people of that demographic that scored their community belonging at that category.

community_belonging %>% 
  distinct(walking_distance_to_nearest_greenspace)

Data

  • feature_code = council area or all of scotland
  • date_code = year between 2013 and 2019
  • measurement = whether the value is a percent, or confidence limit
  • value = percent of people that gave that rating or upper and lower confidence levels for that percentage
  • community_belonging = rating of community belonging
  • gender = Male/Female
  • urban_rural_classification = Urban/Rural
  • simd_quintiles = 80% least deprived/20% most deprived
  • type_of_tenure = Owned Mortgage/Loan / Owned Outright / Social Rented / Private Rented / Other
  • household_type = With Children / Pensioners / Adults
  • ethnicity = White / Other
  • walking_distance_to_nearest_greenspace = More than 10 minutes / Less than 10 minutes / Don’t know

Quality of data

community_belonging %>% 
  group_by(walking_distance_to_nearest_greenspace) %>% 
  summarise(total = n())
(105/(4107+1035))*100

Walking distance to nearest greenspace is likely self reported, only 2% of people do not know the answer and there is a reasonable amount of data that do know.

Experimental plotting

Does this add up to 100%?

community_belonging %>% 
  filter(date_code == 2019,
         gender == "Female",
         ca_name == "West Lothian") %>% 
  select(measurement:community_belonging) %>% 
  pivot_wider(names_from = measurement, values_from = value) %>% 
  clean_names() %>% 
  summarise(sum(percent))

Yes.

Community belonging and green space

community_belonging %>% 
  filter(walking_distance_to_nearest_greenspace != "All",
         ca_name == "Scotland",
         date_code == 2019) %>% 
  pivot_wider(names_from = measurement, values_from = value) %>% 
  clean_names() %>% 
  ggplot(aes(community_belonging, percent, fill = walking_distance_to_nearest_greenspace)) +
  geom_col(position = "dodge") +
  facet_wrap(~walking_distance_to_nearest_greenspace)
community_belonging %>% 
  filter(walking_distance_to_nearest_greenspace != "All",
         ca_name == "Scotland",
         date_code == 2019) %>% 
  pivot_wider(names_from = measurement, values_from = value) %>% 
  clean_names() %>% 
  group_by(walking_distance_to_nearest_greenspace) %>% 
  summarise(total = sum(percent))

It is difficult to quanity the difference.
Perhaps we could use a score for community belonging? (0-5 or (-2)-(+2))

community_belonging %>% 
  distinct(community_belonging)
community_belonging_scored <- community_belonging %>% 
  mutate(belonging_score = case_when(
    community_belonging == "Not at all strongly" ~ 1,
    community_belonging == "Not very strongly" ~ 2,
    community_belonging == "Don't know" ~ 3,
    community_belonging == "Fairly strongly" ~ 4,
    community_belonging == "Very strongly" ~ 5,
  ),
  belonging_score_zeroed = case_when(
    community_belonging == "Not at all strongly" ~ -2,
    community_belonging == "Not very strongly" ~ -1,
    community_belonging == "Don't know" ~ 0,
    community_belonging == "Fairly strongly" ~ 1,
    community_belonging == "Very strongly" ~ 2,
  ))
community_belonging_scored %>% 
  filter(walking_distance_to_nearest_greenspace != "All",
         ca_name == "Scotland",
         date_code == 2019) %>% 
  pivot_wider(names_from = measurement, values_from = value) %>% 
  clean_names() %>% 
  mutate(score = percent * belonging_score,
         score_zero = percent * belonging_score_zeroed) %>% 
  group_by(walking_distance_to_nearest_greenspace) %>% 
  summarise(overall_belonging = mean(score),
            overall_belonging_zero = mean(score_zero)) %>% 
  ggplot(aes(walking_distance_to_nearest_greenspace, overall_belonging_zero)) +
  geom_col()

With normal scoring the maximum possible is 100% scoring 5 -> 500 (0:500)
With zeroed score the maximum possible is 100% scoring 2 -> 200 (-200:200)
This might be better on a scale of -1 to 1.

community_belonging_scored %>% 
  filter(walking_distance_to_nearest_greenspace != "All",
         ca_name == "Scotland",
         date_code == 2019) %>% 
  pivot_wider(names_from = measurement, values_from = value) %>% 
  clean_names() %>% 
  mutate(score_zero = (percent * belonging_score_zeroed)/200) %>% 
  group_by(walking_distance_to_nearest_greenspace) %>% 
  summarise(overall_belonging_zero = mean(score_zero)) %>% 
  ggplot(aes(walking_distance_to_nearest_greenspace, overall_belonging_zero)) +
  geom_col()
community_belonging_scored %>% 
  filter(walking_distance_to_nearest_greenspace != "All",
         ca_name == "Scotland",
         date_code == 2019) %>% 
  pivot_wider(names_from = measurement, values_from = value) %>% 
  clean_names() %>% 
  mutate(score_zero = (percent * belonging_score_zeroed)/200) %>% 
  ggplot(aes(walking_distance_to_nearest_greenspace, score_zero)) +
  geom_point()

App should explore community belonging for each group.

Green spaces

green_spaces
green_spaces %>% 
  distinct(age)

This dataset tells us who has access to green or blue spaces within 10 minutes.

green_spaces %>% 
  left_join(council_areas_clean, by = c("feature_code" = "ca")) %>% 
  filter(ca_name == "Scotland",
         urban_rural_classification == "Urban",
         measurement == "Percent") %>% 
  ggplot(aes(date_code, value, colour = distance_to_nearest_green_or_blue_space)) +
  geom_line()

Neighbourhood Rating

neighbourhood_rating
neighbourhood_rating %>% 
  distinct() %>% 
  nrow()

neighbourhood_rating %>% 
  nrow()
neighbourhood_rating %>% 
  distinct(neighbourhood_rating)

Tab data

lm(rb1 ~ ., data_small) %>% 
  summary()
Warning: using type = "numeric" with a factor response will be ignoredWarning: ‘-’ not meaningful for factorsWarning: ‘^’ not meaningful for factors

Call:
lm(formula = rb1 ~ ., data = data_small)

Residuals:
Error in quantile.default(resid) : (unordered) factors are not allowed
full_data_2019 %>% 
  filter(rand_ok == 1) %>% 
  select(dyear, council, randage, randgender, randecon,
         tenure_harm, hhtype_new, rb1:asb1i)
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShqYW5pdG9yKQ0KbGlicmFyeShoZXJlKQ0KYGBgDQoNCmBgYHtyfQ0KY29tbXVuaXR5X2JlbG9uZ2luZyA8LSBjbGVhbl9uYW1lcyhyZWFkX2NzdihoZXJlKCJyYXdfZGF0YS9jb21tdW5pdHlfYmVsb25naW5nLmNzdiIpKSkNCmdyZWVuX3NwYWNlcyA8LSBjbGVhbl9uYW1lcyhyZWFkX2NzdihoZXJlKCJyYXdfZGF0YS9ncmVlbl9zcGFjZXMuY3N2IikpKQ0KbmVpZ2hib3VyaG9vZF9yYXRpbmcgPC0gY2xlYW5fbmFtZXMocmVhZF9jc3YoaGVyZSgicmF3X2RhdGEvbmVpZ2hib3VyaG9vZF9yYXRpbmcuY3N2IikpKQ0KYGBgDQoNCmBgYHtyfQ0KY29tbXVuaXR5X2JlbG9uZ2luZw0KZ3JlZW5fc3BhY2VzDQpuZWlnaGJvdXJob29kX3JhdGluZw0KYGBgDQojIEV4cGxvcmUgQ29tbXVuaXR5IEJlbG9uZ2luZw0KYGBge3J9DQpjb21tdW5pdHlfYmVsb25naW5nICU+JSANCiAgIHN1bW1hcmlzZShhY3Jvc3MoLmNvbHMgPSBldmVyeXRoaW5nKCksIC5mbnMgPSB+c3VtKGlzLm5hKC54KSkpKQ0KYGBgDQpUaGVyZSBhcmUgbm8gTkEgdmFsdWVzDQoNCmBgYHtyfQ0KY29tbXVuaXR5X2JlbG9uZ2luZyAlPiUgDQogIGRpc3RpbmN0KHVuaXRzKQ0KYGBgDQpUaGVyZSBpcyBvbmx5IDEgdmFsdWUgaW4gdGhpcyBjb2x1bW4uIEl0IGNhbiBiZSByZW1vdmVkIGluIHRoZSBjbGVhbmluZyBzY3JpcHQNCg0KYGBge3J9DQpjb21tdW5pdHlfYmVsb25naW5nICU+JSANCiAgZGlzdGluY3QoKSAlPiUgDQogIG5yb3coKQ0KDQpjb21tdW5pdHlfYmVsb25naW5nICU+JSANCiAgbnJvdygpDQpgYGANCk5vIGR1cGxpY2F0ZXMNCg0KYGBge3J9DQpjb21tdW5pdHlfYmVsb25naW5nICU+JSANCiAgZmlsdGVyKGZlYXR1cmVfY29kZSA9PSAiUzEyMDAwMDM2IiwgeWVhciA9PSAiMjAxNiIsDQogICAgICAgICB3YWxraW5nX2Rpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5zcGFjZSA9PSAiTW9yZSB0aGFuIDEwIG1pbnV0ZXMiKQ0KYGBgDQpUaGVyZSBhcHBlYXIgdG8gYmUgc29tZSBtaXNzaW5nIHZhbHVlcyBzdWNoIGFzIGhvdyBtYW55IHBlb3BsZSB2b3RlZCAiRG9uJ3Qga25vdyIgdG8gY29tbXVuaXR5IGJlbG9uZ2luZyB3aGVyZSB0aGUgd2Fsa2luZyBkaXN0YW5jZSBpcyBncmVhdGVyIHRoYW4gMTAgbWludXRlcy4gSXMgaXQgc2Vuc2libGUgdG8gYXNzdW1lIHRoaXMgaXMgMD8NCg0KYGBge3J9DQpjb21tdW5pdHlfYmVsb25naW5nICU+JSANCiAgZmlsdGVyKGZlYXR1cmVfY29kZSA9PSAiUzEyMDAwMDM2IiwgeWVhciA9PSAiMjAxNiIsDQogICAgICAgICB3YWxraW5nX2Rpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5zcGFjZSA9PSAiTW9yZSB0aGFuIDEwIG1pbnV0ZXMiLA0KICAgICAgICAgbWVhc3VyZW1lbnQgPT0gIlBlcmNlbnQiKSAlPiUgDQogIHN1bW1hcmlzZShzdW0odmFsdWUpKQ0KYGBgDQpZZXMsIHRoZSBvdGhlcnMgYWRkIHVwIHRvIDEwMCUgc28gMCUgdm90ZWQgIkRvbid0IGtub3ciLg0KDQoNCiMjIFdoYXQgaXMgdGhlIGdyYW51bGFyaXR5IG9mIHRoZSBkYXRhPyANCmBgYHtyfQ0KY29tbXVuaXR5X2JlbG9uZ2luZyAlPiUgDQogIGZpbHRlcihkYXRlX2NvZGUgPT0gMjAxOSwNCiAgICAgICAgIGdlbmRlciA9PSAiRmVtYWxlIikNCmBgYA0KVGhlIGZlYXR1cmUgY29kZXMgbG9vayBsaWtlIGNvdW5jaWwgYXJlYXMuIFRoZSBuYW1lIG9mIHRoZSBhcmVhIGlmIGdvaW5nIHRvIGJlIG1vcmUgdXNlZnVsIHRoYW4gY29kZXMuDQohW2RhdGEgc291cmNlXShodHRwczovL3d3dy5vcGVuZGF0YS5uaHMuc2NvdC9rbS9kYXRhc2V0L2dlb2dyYXBoeS1jb2Rlcy1hbmQtbGFiZWxzKQ0KYGBge3J9DQpjb3VuY2lsX2FyZWFzIDwtIGNsZWFuX25hbWVzKHJlYWRfY3N2KGhlcmUoInJhd19kYXRhL2NvdW5jaWxfYXJlYV9jb2Rlcy5jc3YiKSkpDQoNCmNvdW5jaWxfYXJlYXNfY2xlYW4gPC0gY291bmNpbF9hcmVhcyAlPiUgDQogIHNlbGVjdChjYSwgY2FfbmFtZSkgJT4lIA0KICBhZGRfcm93KGNhID0gIlM5MjAwMDAwMyIgLGNhX25hbWUgPSAiU2NvdGxhbmQiKQ0KYGBgDQpTb21lIHJvd3MgYXBwZWFyIHRvIGJlIGZvciB0aGUgd2hvbGUgb2YgU2NvdGxhbmQgc28gSSBoYXZlIGFkZGVkIGEgcm93IGZvciB0aGlzIGNvZGUuDQoNCmBgYHtyfQ0KY29tbXVuaXR5X2JlbG9uZ2luZyA8LSBjb21tdW5pdHlfYmVsb25naW5nICU+JSANCiAgbGVmdF9qb2luKGNvdW5jaWxfYXJlYXNfY2xlYW4sIGJ5ID0gYygiZmVhdHVyZV9jb2RlIiA9ICJjYSIpKQ0KYGBgDQoNCldoZW4gcGxvdHRpbmcgdGhlIG9yZGVyIG9mIGNvbW11bml0eSBiZWxvbmdpbmcgd2lsbCBub3QgbWFrZSBzZW5zZSwgdGhlcmVmb3JlIHRoaXMgc2hvdWxkIGJlIGZhY3RvcmVkLg0KYGBge3J9DQpjb21tdW5pdHlfYmVsb25naW5nIDwtIGNvbW11bml0eV9iZWxvbmdpbmcgJT4lIA0KICBtdXRhdGUoY29tbXVuaXR5X2JlbG9uZ2luZyA9IGZhY3Rvcihjb21tdW5pdHlfYmVsb25naW5nLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiTm90IGF0IGFsbCBzdHJvbmdseSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJOb3QgdmVyeSBzdHJvbmdseSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRvbid0IGtub3ciLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJGYWlybHkgc3Ryb25nbHkiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJWZXJ5IHN0cm9uZ2x5IikpKQ0KYGBgDQo+IEVhY2ggcm93IGFwcGVhcnMgdG8gYmUgYSBkZW1vZ3JhcGhpYyAoZWcuIEZlbWFsZSwgbW9yZSB0aGFuIDEwIG1pbnV0ZXMgdG8gbmVhcmVzdCBncmVlbnNwYWNlLCBldGMpLCBjYXRlZ29yeSBvZiBjb21tdW5pdHkgYmVsb25naW5nLCBtZWFzdXJlbWVudCwgYW5kIHRoZSBwZXJjZW50YWdlIG9mIHBlb3BsZSBvZiB0aGF0IGRlbW9ncmFwaGljIHRoYXQgc2NvcmVkIHRoZWlyIGNvbW11bml0eSBiZWxvbmdpbmcgYXQgdGhhdCBjYXRlZ29yeS4gDQoNCmBgYHtyfQ0KY29tbXVuaXR5X2JlbG9uZ2luZyAlPiUgDQogIGRpc3RpbmN0KHdhbGtpbmdfZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbnNwYWNlKQ0KYGBgDQoNCiMjIERhdGENCg0KKiBmZWF0dXJlX2NvZGUgPSBjb3VuY2lsIGFyZWEgb3IgYWxsIG9mIHNjb3RsYW5kDQoqIGRhdGVfY29kZSA9IHllYXIgYmV0d2VlbiAyMDEzIGFuZCAyMDE5DQoqIG1lYXN1cmVtZW50ID0gd2hldGhlciB0aGUgdmFsdWUgaXMgYSBwZXJjZW50LCBvciBjb25maWRlbmNlIGxpbWl0DQoqIHZhbHVlID0gcGVyY2VudCBvZiBwZW9wbGUgdGhhdCBnYXZlIHRoYXQgcmF0aW5nIG9yIHVwcGVyIGFuZCBsb3dlciBjb25maWRlbmNlIGxldmVscyBmb3IgdGhhdCBwZXJjZW50YWdlDQoqICoqY29tbXVuaXR5X2JlbG9uZ2luZyoqID0gcmF0aW5nIG9mIGNvbW11bml0eSBiZWxvbmdpbmcNCiogZ2VuZGVyID0gTWFsZS9GZW1hbGUNCiogdXJiYW5fcnVyYWxfY2xhc3NpZmljYXRpb24gPSBVcmJhbi9SdXJhbA0KKiBzaW1kX3F1aW50aWxlcyA9IDgwJSBsZWFzdCBkZXByaXZlZC8yMCUgbW9zdCBkZXByaXZlZA0KKiB0eXBlX29mX3RlbnVyZSA9IE93bmVkIE1vcnRnYWdlL0xvYW4gLyBPd25lZCBPdXRyaWdodCAvIFNvY2lhbCBSZW50ZWQgLyBQcml2YXRlIFJlbnRlZCAvIE90aGVyDQoqIGhvdXNlaG9sZF90eXBlID0gV2l0aCBDaGlsZHJlbiAvIFBlbnNpb25lcnMgLyBBZHVsdHMNCiogZXRobmljaXR5ID0gV2hpdGUgLyBPdGhlcg0KKiAqKndhbGtpbmdfZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbnNwYWNlKiogPSBNb3JlIHRoYW4gMTAgbWludXRlcyAvIExlc3MgdGhhbiAxMCBtaW51dGVzIC8gRG9uJ3Qga25vdw0KDQojIyMgUXVhbGl0eSBvZiBkYXRhDQpgYGB7cn0NCmNvbW11bml0eV9iZWxvbmdpbmcgJT4lIA0KICBncm91cF9ieSh3YWxraW5nX2Rpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5zcGFjZSkgJT4lIA0KICBzdW1tYXJpc2UodG90YWwgPSBuKCkpDQpgYGANCmBgYHtyfQ0KKDEwNS8oNDEwNysxMDM1KSkqMTAwDQpgYGANCldhbGtpbmcgZGlzdGFuY2UgdG8gbmVhcmVzdCBncmVlbnNwYWNlIGlzIGxpa2VseSBzZWxmIHJlcG9ydGVkLCBvbmx5IDIlIG9mIHBlb3BsZSBkbyBub3Qga25vdyB0aGUgYW5zd2VyIGFuZCB0aGVyZSBpcyBhIHJlYXNvbmFibGUgYW1vdW50IG9mIGRhdGEgdGhhdCBkbyBrbm93Lg0KDQojIyBFeHBlcmltZW50YWwgcGxvdHRpbmcNCg0KYGBge3J9DQpjb21tdW5pdHlfYmVsb25naW5nICU+JSANCiAgZmlsdGVyKGRhdGVfY29kZSA9PSAyMDE5LA0KICAgICAgICAgZ2VuZGVyID09ICJGZW1hbGUiLA0KICAgICAgICAgY2FfbmFtZSA9PSAiU2NvdGxhbmQiKSAlPiUgDQogIHNlbGVjdChtZWFzdXJlbWVudDpjb21tdW5pdHlfYmVsb25naW5nKSAlPiUgDQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBtZWFzdXJlbWVudCwgdmFsdWVzX2Zyb20gPSB2YWx1ZSkgJT4lIA0KICBjbGVhbl9uYW1lcygpICU+JSANCiAgYXJyYW5nZShjb21tdW5pdHlfYmVsb25naW5nKSAlPiUgDQogIGdncGxvdChhZXMoY29tbXVuaXR5X2JlbG9uZ2luZywgcGVyY2VudCkpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW4gPSB4OTVfcGVyY2VudF9sb3dlcl9jb25maWRlbmNlX2xpbWl0X3BlcmNlbnQsDQogICAgICAgICAgICAgICAgICAgIHltYXggPSB4OTVfcGVyY2VudF91cHBlcl9jb25maWRlbmNlX2xpbWl0X3BlcmNlbnQsDQogICAgICAgICAgICAgICAgICAgIHdpZHRoID0gMC4yKSkNCmBgYA0KRG9lcyB0aGlzIGFkZCB1cCB0byAxMDAlPw0KYGBge3J9DQpjb21tdW5pdHlfYmVsb25naW5nICU+JSANCiAgZmlsdGVyKGRhdGVfY29kZSA9PSAyMDE5LA0KICAgICAgICAgZ2VuZGVyID09ICJGZW1hbGUiLA0KICAgICAgICAgY2FfbmFtZSA9PSAiV2VzdCBMb3RoaWFuIikgJT4lIA0KICBzZWxlY3QobWVhc3VyZW1lbnQ6Y29tbXVuaXR5X2JlbG9uZ2luZykgJT4lIA0KICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gbWVhc3VyZW1lbnQsIHZhbHVlc19mcm9tID0gdmFsdWUpICU+JSANCiAgY2xlYW5fbmFtZXMoKSAlPiUgDQogIHN1bW1hcmlzZShzdW0ocGVyY2VudCkpDQpgYGANClllcy4NCg0KIyMgQ29tbXVuaXR5IGJlbG9uZ2luZyBhbmQgZ3JlZW4gc3BhY2UNCg0KYGBge3J9DQpjb21tdW5pdHlfYmVsb25naW5nICU+JSANCiAgZmlsdGVyKHdhbGtpbmdfZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbnNwYWNlICE9ICJBbGwiLA0KICAgICAgICAgY2FfbmFtZSA9PSAiU2NvdGxhbmQiLA0KICAgICAgICAgZGF0ZV9jb2RlID09IDIwMTkpICU+JSANCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IG1lYXN1cmVtZW50LCB2YWx1ZXNfZnJvbSA9IHZhbHVlKSAlPiUgDQogIGNsZWFuX25hbWVzKCkgJT4lIA0KICBnZ3Bsb3QoYWVzKGNvbW11bml0eV9iZWxvbmdpbmcsIHBlcmNlbnQsIGZpbGwgPSB3YWxraW5nX2Rpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5zcGFjZSkpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIGZhY2V0X3dyYXAofndhbGtpbmdfZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbnNwYWNlKQ0KYGBgDQpgYGB7cn0NCmNvbW11bml0eV9iZWxvbmdpbmcgJT4lIA0KICBmaWx0ZXIod2Fsa2luZ19kaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuc3BhY2UgIT0gIkFsbCIsDQogICAgICAgICBjYV9uYW1lID09ICJTY290bGFuZCIsDQogICAgICAgICBkYXRlX2NvZGUgPT0gMjAxOSkgJT4lIA0KICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gbWVhc3VyZW1lbnQsIHZhbHVlc19mcm9tID0gdmFsdWUpICU+JSANCiAgY2xlYW5fbmFtZXMoKSAlPiUgDQogIGdyb3VwX2J5KHdhbGtpbmdfZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbnNwYWNlKSAlPiUgDQogIHN1bW1hcmlzZSh0b3RhbCA9IHN1bShwZXJjZW50KSkNCmBgYA0KSXQgaXMgZGlmZmljdWx0IHRvIHF1YW5pdHkgdGhlIGRpZmZlcmVuY2UuICAgDQpQZXJoYXBzIHdlIGNvdWxkIHVzZSBhIHNjb3JlIGZvciBjb21tdW5pdHkgYmVsb25naW5nPyAoMC01IG9yICgtMiktKCsyKSkNCg0KYGBge3J9DQpjb21tdW5pdHlfYmVsb25naW5nICU+JSANCiAgZGlzdGluY3QoY29tbXVuaXR5X2JlbG9uZ2luZykNCmBgYA0KDQpgYGB7cn0NCmNvbW11bml0eV9iZWxvbmdpbmdfc2NvcmVkIDwtIGNvbW11bml0eV9iZWxvbmdpbmcgJT4lIA0KICBtdXRhdGUoYmVsb25naW5nX3Njb3JlID0gY2FzZV93aGVuKA0KICAgIGNvbW11bml0eV9iZWxvbmdpbmcgPT0gIk5vdCBhdCBhbGwgc3Ryb25nbHkiIH4gMSwNCiAgICBjb21tdW5pdHlfYmVsb25naW5nID09ICJOb3QgdmVyeSBzdHJvbmdseSIgfiAyLA0KICAgIGNvbW11bml0eV9iZWxvbmdpbmcgPT0gIkRvbid0IGtub3ciIH4gMywNCiAgICBjb21tdW5pdHlfYmVsb25naW5nID09ICJGYWlybHkgc3Ryb25nbHkiIH4gNCwNCiAgICBjb21tdW5pdHlfYmVsb25naW5nID09ICJWZXJ5IHN0cm9uZ2x5IiB+IDUsDQogICksDQogIGJlbG9uZ2luZ19zY29yZV96ZXJvZWQgPSBjYXNlX3doZW4oDQogICAgY29tbXVuaXR5X2JlbG9uZ2luZyA9PSAiTm90IGF0IGFsbCBzdHJvbmdseSIgfiAtMiwNCiAgICBjb21tdW5pdHlfYmVsb25naW5nID09ICJOb3QgdmVyeSBzdHJvbmdseSIgfiAtMSwNCiAgICBjb21tdW5pdHlfYmVsb25naW5nID09ICJEb24ndCBrbm93IiB+IDAsDQogICAgY29tbXVuaXR5X2JlbG9uZ2luZyA9PSAiRmFpcmx5IHN0cm9uZ2x5IiB+IDEsDQogICAgY29tbXVuaXR5X2JlbG9uZ2luZyA9PSAiVmVyeSBzdHJvbmdseSIgfiAyLA0KICApKQ0KYGBgDQoNCmBgYHtyfQ0KY29tbXVuaXR5X2JlbG9uZ2luZ19zY29yZWQgJT4lIA0KICBmaWx0ZXIod2Fsa2luZ19kaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuc3BhY2UgIT0gIkFsbCIsDQogICAgICAgICBjYV9uYW1lID09ICJTY290bGFuZCIsDQogICAgICAgICBkYXRlX2NvZGUgPT0gMjAxOSkgJT4lIA0KICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gbWVhc3VyZW1lbnQsIHZhbHVlc19mcm9tID0gdmFsdWUpICU+JSANCiAgY2xlYW5fbmFtZXMoKSAlPiUgDQogIG11dGF0ZShzY29yZSA9IHBlcmNlbnQgKiBiZWxvbmdpbmdfc2NvcmUsDQogICAgICAgICBzY29yZV96ZXJvID0gcGVyY2VudCAqIGJlbG9uZ2luZ19zY29yZV96ZXJvZWQpICU+JSANCiAgZ3JvdXBfYnkod2Fsa2luZ19kaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuc3BhY2UpICU+JSANCiAgc3VtbWFyaXNlKG92ZXJhbGxfYmVsb25naW5nID0gbWVhbihzY29yZSksDQogICAgICAgICAgICBvdmVyYWxsX2JlbG9uZ2luZ196ZXJvID0gbWVhbihzY29yZV96ZXJvKSkgJT4lIA0KICBnZ3Bsb3QoYWVzKHdhbGtpbmdfZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbnNwYWNlLCBvdmVyYWxsX2JlbG9uZ2luZ196ZXJvKSkgKw0KICBnZW9tX2NvbCgpDQpgYGANCldpdGggbm9ybWFsIHNjb3JpbmcgdGhlIG1heGltdW0gcG9zc2libGUgaXMgMTAwJSBzY29yaW5nIDUgLT4gNTAwICgwOjUwMCkgIA0KV2l0aCB6ZXJvZWQgc2NvcmUgdGhlIG1heGltdW0gcG9zc2libGUgaXMgMTAwJSBzY29yaW5nIDIgLT4gMjAwICgtMjAwOjIwMCkgIA0KVGhpcyBtaWdodCBiZSBiZXR0ZXIgb24gYSBzY2FsZSBvZiAtMSB0byAxLiAgDQoNCmBgYHtyfQ0KY29tbXVuaXR5X2JlbG9uZ2luZ19zY29yZWQgJT4lIA0KICBmaWx0ZXIod2Fsa2luZ19kaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuc3BhY2UgIT0gIkFsbCIsDQogICAgICAgICBjYV9uYW1lID09ICJTY290bGFuZCIsDQogICAgICAgICBkYXRlX2NvZGUgPT0gMjAxOSkgJT4lIA0KICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gbWVhc3VyZW1lbnQsIHZhbHVlc19mcm9tID0gdmFsdWUpICU+JSANCiAgY2xlYW5fbmFtZXMoKSAlPiUgDQogIG11dGF0ZShzY29yZV96ZXJvID0gKHBlcmNlbnQgKiBiZWxvbmdpbmdfc2NvcmVfemVyb2VkKS8yMDApICU+JSANCiAgZ3JvdXBfYnkod2Fsa2luZ19kaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuc3BhY2UpICU+JSANCiAgc3VtbWFyaXNlKG92ZXJhbGxfYmVsb25naW5nX3plcm8gPSBtZWFuKHNjb3JlX3plcm8pKSAlPiUgDQogIGdncGxvdChhZXMod2Fsa2luZ19kaXN0YW5jZV90b19uZWFyZXN0X2dyZWVuc3BhY2UsIG92ZXJhbGxfYmVsb25naW5nX3plcm8pKSArDQogIGdlb21fY29sKCkNCmBgYCANCg0KYGBge3J9DQpjb21tdW5pdHlfYmVsb25naW5nX3Njb3JlZCAlPiUgDQogIGZpbHRlcih3YWxraW5nX2Rpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5zcGFjZSAhPSAiQWxsIiwNCiAgICAgICAgIGNhX25hbWUgPT0gIlNjb3RsYW5kIiwNCiAgICAgICAgIGRhdGVfY29kZSA9PSAyMDE5KSAlPiUgDQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBtZWFzdXJlbWVudCwgdmFsdWVzX2Zyb20gPSB2YWx1ZSkgJT4lIA0KICBjbGVhbl9uYW1lcygpICU+JSANCiAgbXV0YXRlKHNjb3JlX3plcm8gPSAocGVyY2VudCAqIGJlbG9uZ2luZ19zY29yZV96ZXJvZWQpLzIwMCkgJT4lIA0KICBnZ3Bsb3QoYWVzKHdhbGtpbmdfZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbnNwYWNlLCBzY29yZV96ZXJvKSkgKw0KICBnZW9tX3BvaW50KCkNCmBgYCAgDQoNCkFwcCBzaG91bGQgZXhwbG9yZSBjb21tdW5pdHkgYmVsb25naW5nIGZvciBlYWNoIGdyb3VwLg0KDQojIEdyZWVuIHNwYWNlcw0KYGBge3J9DQpncmVlbl9zcGFjZXMNCmdyZWVuX3NwYWNlcyAlPiUgDQogIGRpc3RpbmN0KGFnZSkNCmBgYA0KKiBmZWF0dXJlX2NvZGUgPSBjb3VuY2lsIGFyZWEgb3IgYWxsIG9mIHNjb3RsYW5kDQoqIGRhdGVfY29kZSA9IHllYXIgYmV0d2VlbiAyMDEzIGFuZCAyMDE5DQoqIG1lYXN1cmVtZW50ID0gd2hldGhlciB0aGUgdmFsdWUgaXMgYSBwZXJjZW50LCBvciBjb25maWRlbmNlIGxpbWl0DQoqIHZhbHVlID0gcGVyY2VudCBvZiBwZW9wbGUgdGhhdCBnYXZlIHRoYXQgcmF0aW5nIG9yIHVwcGVyIGFuZCBsb3dlciBjb25maWRlbmNlIGxldmVscyBmb3IgdGhhdCBwZXJjZW50YWdlDQoqICoqZGlzdGFuY2VfdG9fbmVhcmVzdF9ncmVlbl9vcl9ibHVlX3NwYWNlKiogPSA1IG1pbnV0ZSB3YWxrIG9yIGxlc3MgLyA2LTEwIG1pbnV0ZSB3YWxrIC8gMTErIG1pbnV0ZSB3YWxrIC8gRG9uJ3Qga25vdw0KKiBhZ2UgPSAxNi0zNCAvIDM1LTY0IC8gNjUrDQoqIGdlbmRlciA9IE1hbGUvRmVtYWxlDQoqIHVyYmFuX3J1cmFsX2NsYXNzaWZpY2F0aW9uID0gVXJiYW4vUnVyYWwNCiogc2ltZF9xdWludGlsZXMgPSA4MCUgbGVhc3QgZGVwcml2ZWQvMjAlIG1vc3QgZGVwcml2ZWQNCiogdHlwZV9vZl90ZW51cmUgPSBPd25lZCBNb3J0Z2FnZS9Mb2FuIC8gT3duZWQgT3V0cmlnaHQgLyBTb2NpYWwgUmVudGVkIC8gUHJpdmF0ZSBSZW50ZWQgLyBPdGhlcg0KKiBob3VzZWhvbGRfdHlwZSA9IFdpdGggQ2hpbGRyZW4gLyBQZW5zaW9uZXJzIC8gQWR1bHRzDQoqIGV0aG5pY2l0eSA9IFdoaXRlIC8gT3RoZXINCg0KVGhpcyBkYXRhc2V0IHRlbGxzIHVzIHdobyBoYXMgYWNjZXNzIHRvIGdyZWVuIG9yIGJsdWUgc3BhY2VzIHdpdGhpbiAxMCBtaW51dGVzLg0KDQpgYGB7cn0NCmdyZWVuX3NwYWNlcyAlPiUgDQogIGxlZnRfam9pbihjb3VuY2lsX2FyZWFzX2NsZWFuLCBieSA9IGMoImZlYXR1cmVfY29kZSIgPSAiY2EiKSkgJT4lIA0KICBmaWx0ZXIoY2FfbmFtZSA9PSAiU2NvdGxhbmQiLA0KICAgICAgICAgdXJiYW5fcnVyYWxfY2xhc3NpZmljYXRpb24gPT0gIlVyYmFuIiwNCiAgICAgICAgIG1lYXN1cmVtZW50ID09ICJQZXJjZW50IikgJT4lIA0KICBnZ3Bsb3QoYWVzKGRhdGVfY29kZSwgdmFsdWUsIGNvbG91ciA9IGRpc3RhbmNlX3RvX25lYXJlc3RfZ3JlZW5fb3JfYmx1ZV9zcGFjZSkpICsNCiAgZ2VvbV9saW5lKCkNCmBgYA0KIyBOZWlnaGJvdXJob29kIFJhdGluZw0KDQpgYGB7cn0NCm5laWdoYm91cmhvb2RfcmF0aW5nDQpgYGANCmBgYHtyfQ0KbmVpZ2hib3VyaG9vZF9yYXRpbmcgJT4lIA0KICBkaXN0aW5jdCgpICU+JSANCiAgbnJvdygpDQoNCm5laWdoYm91cmhvb2RfcmF0aW5nICU+JSANCiAgbnJvdygpDQpgYGANCg0KDQoNCmBgYHtyfQ0KbmVpZ2hib3VyaG9vZF9yYXRpbmcgJT4lIA0KICBkaXN0aW5jdChuZWlnaGJvdXJob29kX3JhdGluZykNCmBgYA0KDQojIFRhYiBkYXRhDQoNCmBgYHtyfQ0KZnVsbF9kYXRhXzIwMTkgPC0gcmVhZC5kZWxpbShoZXJlKCJyYXdfZGF0YS90YWIvc2hzMjAxOV9zb2NpYWxfcHVibGljLnRhYiIpKQ0KYGBgDQpgYGB7cn0NCmRhdGFfc21hbGwgPC0gZnVsbF9kYXRhXzIwMTkgJT4lIA0KICBmaWx0ZXIocmFuZF9vayA9PSAxKSAlPiUgDQogIHNlbGVjdChyYW5kYWdlLCByYW5kZ2VuZGVyLCByYW5kZWNvbiwNCiAgICAgICAgIHRlbnVyZV9oYXJtLCBoaHR5cGVfbmV3LCByYjE6YXNiMWkpICU+JQ0KICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLm51bWVyaWMpLCBhcy5mYWN0b3IpKSAlPiUgDQogIG11dGF0ZShyYW5kYWdlID0gYXMubnVtZXJpYyhyYW5kYWdlKSkNCmBgYA0KDQpgYGB7cn0NCmxtKHJiMSB+IC4sIGRhdGFfc21hbGwpICU+JSANCiAgc3VtbWFyeSgpDQpgYGANCg0KDQoNCmBgYHtyfQ0KZnVsbF9kYXRhXzIwMTkgJT4lIA0KICBmaWx0ZXIocmFuZF9vayA9PSAxKSAlPiUgDQogIHNlbGVjdChkeWVhciwgY291bmNpbCwgcmFuZGFnZSwgcmFuZGdlbmRlciwgcmFuZGVjb24sDQogICAgICAgICB0ZW51cmVfaGFybSwgaGh0eXBlX25ldywgcmIxOmFzYjFpKSAlPiUgDQogIG11dGF0ZShjb3VuY2lsID0gY2FzZV93aGVuKA0KICAgIGNvdW5jaWwgPT0gIlQiIH4gIk1vcmF5IiwNCiAgY291bmNpbCA9PSAiNSIgfiAiV2VzdCBMb3RoaWFuIiwNCiAgY291bmNpbCA9PSAiWSIgfiAiUmVuZnJld3NoaXJlIiwNCiAgY291bmNpbCA9PSAiQyIgfiAiQW5ndXMiLA0KICBjb3VuY2lsID09ICJSIiB+ICJJbnZlcmNseWRlIiwNCiAgY291bmNpbCA9PSAiVSIgfiAiTm9ydGggQXlyc2hpcmUiLA0KICBjb3VuY2lsID09ICJYIiB+ICJQZXJ0aCBhbmQgS2lucm9zcyIsDQogIGNvdW5jaWwgPT0gIjYiIH4gIkVpbGVhbiBTaWFyIiwNCiAgY291bmNpbCA9PSAiQiIgfiAiQWJlcmRlZW5zaGlyZSIsDQogIGNvdW5jaWwgPT0gIkQiIH4gIkFyZ3lsbCBhbmQgQnV0ZSIsDQogIGNvdW5jaWwgPT0gIkUiIH4gIlNjb3R0aXNoIEJvcmRlcnMiLA0KICBjb3VuY2lsID09ICJIIiB+ICJEdW5kZWUgQ2l0eSIsDQogIGNvdW5jaWwgPT0gIjEiIH4gIlNvdXRoIEF5cnNoaXJlIiwNCiAgY291bmNpbCA9PSAiMiIgfiAiU291dGggTGFuYXJrc2hpcmUiLA0KICBjb3VuY2lsID09ICJGIiB+ICJDbGFja21hbm5hbnNoaXJlIiwNCiAgY291bmNpbCA9PSAiRyIgfiAiRHVtZnJpZXMgYW5kIEdhbGxvd2F5IiwNCiAgY291bmNpbCA9PSAiIiB+ICIiLA0KICBjb3VuY2lsID09ICIiIH4gIiIsDQogIGNvdW5jaWwgPT0gIiIgfiAiIiwNClZhbHVlID0gICAJTGFiZWwgPSANCglWYWx1ZSA9ICAgCUxhYmVsID0gDQoJVmFsdWUgPSAgIAlMYWJlbCA9IA0KCVZhbHVlID0gUSAgCUxhYmVsID0gSGlnaGxhbmQNCglWYWx1ZSA9IDMgIAlMYWJlbCA9IFN0aXJsaW5nDQoJVmFsdWUgPSBBICAJTGFiZWwgPSBBYmVyZGVlbiBDaXR5DQoJVmFsdWUgPSA0ICAJTGFiZWwgPSBXZXN0IER1bWJhcnRvbnNoaXJlDQoJVmFsdWUgPSBMICAJTGFiZWwgPSBFYXN0IFJlbmZyZXdzaGlyZQ0KCVZhbHVlID0gTiAgCUxhYmVsID0gRmFsa2lyaw0KCVZhbHVlID0gSyAgCUxhYmVsID0gRWFzdCBMb3RoaWFuDQoJVmFsdWUgPSBPICAJTGFiZWwgPSBGaWZlDQoJVmFsdWUgPSBKICAJTGFiZWwgPSBFYXN0IER1bWJhcnRvbnNoaXJlDQoJVmFsdWUgPSBXICAJTGFiZWwgPSBPcmtuZXkNCglWYWx1ZSA9IFAgIAlMYWJlbCA9IEdsYXNnb3cgQ2l0eQ0KCVZhbHVlID0gWiAgCUxhYmVsID0gU2hldGxhbmQNCglWYWx1ZSA9IFYgIAlMYWJlbCA9IE5vcnRoIExhbmFya3NoaXJlDQoJVmFsdWUgPSBJICAJTGFiZWwgPSBFYXN0IEF5cnNoaXJlDQoJVmFsdWUgPSBTICAJTGFiZWwgPSBNaWRsb3RoaWFuDQoJVmFsdWUgPSBNICAJTGFiZWwgPSBFZGluYnVyZ2ggQ2l0eQ0KDQogICkpDQpgYGANCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg==